#ifndef DEVICE_LIBRARY_H
#define DEVICE_LIBRARY_H
#include <iostream>
#include <string>
#include <memory>
// 定义设备类型常量
enum DeviceType {
    DEFAULT_REGULAR_TYPE = 3,
    DEFAULT_SMART_TYPE = 8
};
// 抽象基类：电力设备
class Device {
public:
    Device(std::string id, float voltage, float current, int state);
    virtual ~Device();  // 虚析构函数确保正确释放派生类资源

    // 纯虚函数 - 要求派生类实现设备信息打印
    virtual void printAll() const = 0;

protected:
    std::string deviceId;
    float voltage;
    float current;
    int state;
};

// 常规设备类
class RegularDevice : public Device {
public:
    RegularDevice(std::string id, float v, float c, int s, int type = DeviceType::DEFAULT_REGULAR_TYPE);
    RegularDevice(const RegularDevice& other); // 拷贝构造函数
    RegularDevice& operator=(const RegularDevice& other); // 拷贝赋值运算符
    ~RegularDevice() override; // 析构函数

    void printAll() const override;

private:
    int regularType;
};

// 智能设备类
class SmartDevice : public Device {
public:
    SmartDevice(std::string id, float v, float c, int s, int smartType = DeviceType::DEFAULT_SMART_TYPE, int funcStatus = 0);
    SmartDevice(const SmartDevice& other); // 拷贝构造函数
    SmartDevice& operator=(const SmartDevice& other); // 拷贝赋值运算符
    ~SmartDevice() override; // 析构函数

    void printAll() const override;
    void autoAdjustVoltage(float newVoltage);

private:
    int smartType;
    int functionStatus;
};

// 接口类：DeviceControllerInterface
class DeviceControllerInterface {
public:
    virtual ~DeviceControllerInterface();

    // 设备控制操作（稳定接口）
    virtual void control(Device& device) const = 0;

    /*
    在control代码之后添加新的虚函数 adjustVoltage：
    1、虚函数通过虚函数表（vtable）实现。每个类的虚函数表包含所有虚函数的指针，按照声明的顺序排列。
    2、C++ 的虚函数表（vtable）中是向后兼容的，新的虚函数会被添加到虚函数表的末尾，不会影响已有的虚函数（如 control）的布局。
    3、新增虚函数不会改变类的大小，因为虚函数表的指针是静态的，旧程序的二进制代码仍然能够正确解析类的大小和布局。
    */
    // 新增接口：调整电压
    // virtual void adjustVoltage(Device& device, float newVoltage) const = 0;


protected:
    DeviceControllerInterface() = default;
};

// 工厂函数，用于创建接口实例
std::shared_ptr<DeviceControllerInterface> createDeviceController();

#endif // DEVICE_LIBRARY_H